package com.writing.controller;

import com.alibaba.fastjson2.JSONObject;
import com.writing.common.Result;
import com.writing.dto.AIGenerateRequest;
import com.writing.entity.ApiConfig;
import com.writing.service.AIService;
import com.writing.service.ApiConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * AI服务控制器
 * 所有AI相关的API都通过这个控制器，确保API Key安全地由后端管理
 */
@Slf4j
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class AIController {

    private final AIService aiService;
    private final ApiConfigService apiConfigService;
    
    // 用于管理SSE连接
    private final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();

    /**
     * 生成文本（非流式）
     */
    @PostMapping("/generate")
    public Result<String> generateText(@RequestBody AIGenerateRequest request) {
        try {
            log.info("收到文本生成请求，类型: {}", request.getType());
            
            // 验证请求
            if (request.getPrompt() == null && (request.getMessages() == null || request.getMessages().isEmpty())) {
                return Result.error("prompt和messages不能同时为空");
            }
            
            if (request.getModel() == null) {
                request.setModel("gpt-3.5-turbo");
            }
            
            String result = aiService.generateText(request);
            return Result.success(result);
        } catch (Exception e) {
            log.error("生成文本失败", e);
            return Result.error("生成文本失败: " + e.getMessage());
        }
    }

    /**
     * 流式生成文本（使用Server-Sent Events）
     */
    @PostMapping(value = "/generate-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter generateTextStream(@RequestBody AIGenerateRequest request) {
        log.info("收到流式生成请求，类型: {}", request.getType());
        
        // 创建SSE emitter
        SseEmitter emitter = new SseEmitter(300000L); // 5分钟超时
        String emitterId = UUID.randomUUID().toString();
        emitters.put(emitterId, emitter);

        // 异步处理流式生成
        new Thread(() -> {
            try {
                // 验证请求
                if (request.getPrompt() == null && (request.getMessages() == null || request.getMessages().isEmpty())) {
                    sendError(emitter, "prompt和messages不能同时为空");
                    return;
                }
                
                // 确保使用前端传递的模型，如果没有则使用默认值
                if (request.getModel() == null || request.getModel().trim().isEmpty()) {
                    // 如果没有指定模型，尝试从 API 配置中获取
                    ApiConfig apiConfig = apiConfigService.getEnabledConfigs().stream()
                            .findFirst()
                            .orElse(null);
                    if (apiConfig != null && apiConfig.getSelectedModel() != null) {
                        request.setModel(apiConfig.getSelectedModel());
                        log.info("使用 API 配置中的默认模型: {}", apiConfig.getSelectedModel());
                    } else {
                        request.setModel("gpt-3.5-turbo");
                        log.info("使用系统默认模型: gpt-3.5-turbo");
                    }
                } else {
                    log.info("使用前端指定的模型: {}", request.getModel());
                }

                // 调用AI服务的流式方法
                aiService.generateTextStream(request, new AIService.StreamCallback() {
                    @Override
                    public void onChunk(String chunk) {
                        try {
                            // 将内容包装为 JSON 格式，以便前端正确解析
                            JSONObject chunkData = new JSONObject();
                            chunkData.put("chunk", chunk);
                            
                            SseEmitter.SseEventBuilder event = SseEmitter.event()
                                    .id(UUID.randomUUID().toString())
                                    .name("chunk")
                                    .data(chunkData.toJSONString())
                                    .reconnectTime(1000);
                            emitter.send(event);
                        } catch (IllegalStateException e) {
                            // Emitter 已经完成，忽略
                            log.debug("SseEmitter已完成，忽略chunk发送");
                        } catch (IOException e) {
                            // 连接已关闭，忽略
                            log.debug("连接已关闭，忽略chunk发送");
                        } catch (Exception e) {
                            // 其他错误，记录日志但不中断流程
                            log.warn("发送chunk时出错", e);
                        }
                    }

                    @Override
                    public void onError(Exception error) {
                        sendError(emitter, error.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        try {
                            // 发送完成标记
                            JSONObject doneData = new JSONObject();
                            doneData.put("done", true);
                            
                            SseEmitter.SseEventBuilder event = SseEmitter.event()
                                    .id(UUID.randomUUID().toString())
                                    .name("done")
                                    .data(doneData.toJSONString())
                                    .reconnectTime(1000);
                            emitter.send(event);
                            emitter.complete();
                        } catch (IllegalStateException e) {
                            // Emitter 已经完成，忽略
                            log.debug("SseEmitter已完成，忽略完成事件发送");
                        } catch (IOException e) {
                            // 连接已关闭，忽略
                            log.debug("连接已关闭，忽略完成事件发送");
                        } catch (Exception e) {
                            // 其他错误，记录日志
                            log.warn("发送完成事件时出错", e);
                        } finally {
                            emitters.remove(emitterId);
                        }
                    }
                });
            } catch (Exception e) {
                log.error("流式生成错误", e);
                sendError(emitter, "流式生成失败: " + e.getMessage());
                emitters.remove(emitterId);
            }
        }).start();

        return emitter;
    }

    /**
     * 发送错误信息
     */
    private void sendError(SseEmitter emitter, String message) {
        try {
            // 将错误信息包装为 JSON 格式
            JSONObject errorData = new JSONObject();
            errorData.put("error", message);
            
            SseEmitter.SseEventBuilder event = SseEmitter.event()
                    .id(UUID.randomUUID().toString())
                    .name("error")
                    .data(errorData.toJSONString())
                    .reconnectTime(1000);
            emitter.send(event);
            // 注意：不要调用 completeWithError，因为这会导致 Spring 异常处理器介入
            // 而异常处理器无法处理 text/event-stream 类型的响应
            // 直接调用 complete() 即可
            emitter.complete();
        } catch (IllegalStateException e) {
            // Emitter 已经完成，忽略
            log.debug("SseEmitter已完成，忽略错误发送");
        } catch (IOException e) {
            log.error("发送错误信息失败", e);
            try {
                emitter.complete();
            } catch (Exception ex) {
                // 忽略
            }
        } catch (Exception e) {
            log.error("发送错误信息时发生异常", e);
            try {
                emitter.complete();
            } catch (Exception ex) {
                // 忽略
            }
        }
    }

}

